﻿//-----------------------------------------------------------------------
// <copyright file="Attribute.cs" company="Craig Longford (deltawolf7@gmail.com)">
//     Copyright (c) Craig Longford. All rights reserved.
// </copyright>
//---------------------------------------------------------------------

namespace Delta.Mercury.Business.Commerce
{
    using System;
    using Delta.Data.DataExpress;
    using Delta.Mercury.Business.Exceptions;

    /// <summary>
    /// Product attribute class
    /// </summary>
    [Serializable]
    public class Attribute : IdentifierBase, IDataServicable
    {
        #region Members
        /// <summary>
        /// Attribute type unique identifier
        /// </summary>
        private Guid typeGuid;

        /// <summary>
        /// Attribute type name
        /// </summary>
        private string typeName;

        /// <summary>
        /// Attrbiute name
        /// </summary>
        private string name;

        /// <summary>
        /// Attrbute value
        /// </summary>
        private string value;
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the Attribute class.
        /// </summary>
        public Attribute()
            : this(string.Empty, string.Empty, 0, Guid.Empty)
        {
        }

        /// <summary>
        /// Initializes a new instance of the Attribute class.
        /// </summary>
        /// <param name="name">Attribute name</param>
        /// <param name="value">Attribute value</param>
        /// <param name="sortOrder">Attribute sort order</param>
        /// <param name="typeGuid">Attribute type unique identifier</param>
        public Attribute(string name, string value, int sortOrder, Guid typeGuid)
            : base()
        {
            this.name = name;
            this.value = value;
            this.SortOrder = sortOrder;
            this.typeGuid = typeGuid;

            AttributeType attributeType = AttributeType.Load(typeGuid);
            if (attributeType != null)
            {
                this.typeName = attributeType.Name;
            }
            else
            {
                this.typeName = "Unknown";
            }
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets the attribute type name
        /// </summary>
        public string AttributeTypeName
        {
            get
            {
                return this.typeName;
            }
        }

        /// <summary>
        /// Gets or sets the owner guid
        /// </summary>
        public Guid OwnerGuid { get; set; }

        /// <summary>
        /// Gets or sets the attribute type name
        /// </summary>
        public Guid AttributeTypeGuid 
        {
            get
            {
                return this.typeGuid;
            }

            set
            {
                this.typeGuid = value;
                if (value != Guid.Empty)
                {
                    AttributeType type = AttributeType.Load(value);
                    if (type != null)
                    {
                        this.typeName = type.Name;
                    }
                    else
                    {
                        this.typeName = "Unknown";
                    }
                }
            }
        } 

        /// <summary>
        /// Gets or sets the attribute name
        /// </summary>
        public string Name
        {
            get
            {
                return this.name;
            }

            set
            {
                if (value.Length < 1)
                {
                    throw new InvalidLengthException("Attribute name must be a minimum of 1 characters.");
                }

                if (value.Length > 30)
                {
                    throw new InvalidLengthException("Attribute name must be a maximum of 30 characters.");
                }

                this.name = value;
            }
        }

        /// <summary>
        /// Gets or sets the attribute value
        /// </summary>
        public string Value
        {
            get
            {
                return this.value;
            }

            set
            {
                if (value.Length < 1)
                {
                    throw new InvalidLengthException("Attribute value must be a minimum of 1 characters.");
                }

                if (value.Length > 255)
                {
                    throw new InvalidLengthException("Attribute value must be a maximum of 255 characters.");
                }

                this.value = value;
            }
        }

        /// <summary>
        /// Gets or sets the attribute sort order
        /// </summary>
        public int SortOrder { get; set; }
        #endregion

        #region Load Methods
        /// <summary>
        /// Load attribute by unique identifier
        /// </summary>
        /// <param name="uniqueidentifeir">Unique identifier</param>
        /// <returns>Product attribute</returns>
        public static Attribute Load(Guid uniqueidentifeir)
        {
            Parameters parameters = new Parameters();
            parameters.Add(new Parameter("Guid", uniqueidentifeir));
            return DataAccess.GetSingle<Attribute>("LoadAttribute", System.Data.CommandType.StoredProcedure, parameters);
        }
        #endregion

        #region Save Methods
        /// <summary>
        /// Save attribute
        /// </summary>
        public void Save()
        {
            DataAccess.NonQuery("SaveAttribute", System.Data.CommandType.StoredProcedure, GetSaveParameters());
        }
        #endregion

        #region Delete Methods
        /// <summary>
        /// Delete attribute
        /// </summary>
        public void Delete()
        {
            Parameters parameters = new Parameters();
            parameters.Add(new Parameter("Guid", this.Guid));
            DataAccess.NonQuery("DeleteAttribute", System.Data.CommandType.StoredProcedure, parameters);
        }
        #endregion

        #region Fill Methods
        /// <summary>
        /// Fill object from data reader
        /// </summary>
        /// <param name="reader">Data reader</param>
        public void Fill(System.Data.IDataReader reader)
        {
            this.Guid = Helper.ToGuid(reader["Guid"]);
            this.name = Helper.ToString(reader["Name"]);
            this.value = Helper.ToString(reader["Value"]);
            this.typeName = Helper.ToString(reader["AttributeName"]);
            this.typeGuid = Helper.ToGuid(reader["AttributeGuid"]);
            this.OwnerGuid = Helper.ToGuid(reader["OwnerGuid"]);
            this.SortOrder = Helper.ToInt(reader["SortOrder"]);
        }
        #endregion

        #region Get Save Parameters
        /// <summary>
        /// Get save parameters
        /// </summary>
        /// <returns>Parameter collection</returns>
        public Parameters GetSaveParameters()
        {
            Parameters parameters = new Parameters();
            parameters.Add(new Parameter("Guid", this.Guid));
            parameters.Add(new Parameter("AttributeGuid", this.AttributeTypeGuid));
            parameters.Add(new Parameter("OwnerGuid", this.OwnerGuid));
            parameters.Add(new Parameter("Name", this.Name));
            parameters.Add(new Parameter("Value", this.Value));
            parameters.Add(new Parameter("SortOrder", this.SortOrder));
            parameters.Add(new Parameter("AttributeName", this.AttributeTypeName));
            return parameters;
        }
        #endregion
    }
}
